﻿#ifndef CSTRUCT_H
#define CSTRUCT_H

#include <QString>
#include <QStringList>
#include <QObject>
#include <QVariant>
#include <QMap>
#include <QSharedPointer>
#include <QMap>
#include <QJsonObject>
#include <QJsonValue>
#include <QColor>

class IModel: public QObject{

    Q_OBJECT

public:
    /**
     * @brief 构造函数
     * @param parent 父对象
     */
    IModel(QObject* parent = nullptr):QObject(parent),m_fieldCount(0){};

    /**
     * @brief 构造函数
     * @param fieldCount 字段计数
     * @param parent 父对象
     */
    IModel(int fieldCount, QObject* parent = nullptr):QObject(parent),m_fieldCount(fieldCount){};

    /**
     * 复制构造函数，创建一个新实例，内容复制自另一个实例。
     * @param m  要复制的信息实例。
     */
    IModel(const IModel& d);

    // 声明虚析构函数
    virtual ~IModel() {}

public:
    /**
     * @brief 获取字段名称列表
     * @return QStringList 包含所有字段名称的列表
     */
    QStringList getFieldNameList();
    /**
     * @brief 根据列数获取字段名称
     * @param col 列索引
     * @return QString 根据列数获取的字段名称
     */
    virtual QString getFieldNameByCol(int col)=0;
    /**
     * @brief 根据字段名称获取字段值
     * @param name 字段名称
     * @return QVariant 根据字段名称获取的字段值
     */
    virtual QVariant getFieldValueByFielddName(const QString& name) = 0;
    /**
     * @brief 根据列数设置字段值
     * @param col 列索引
     * @param value 要设置的字段值
     */
    virtual void setFieldValueByCol(int col, const QVariant& value) = 0;

    /**
     * @brief 根据列数设置字段背景颜色
     * @param col 列索引
     * @param value 要设置的颜色
     */
    virtual void setFieldBgColor(const QString& field, const QString& color);

    /**
     * @brief 根据列数读取字段背景颜色
     * @param col 列索引
     * @param return 颜色字符串
     */
    virtual QString getFieldBgColor(const QString& field);

    /**
     * 根据字段名获取列索引。
     * 
     * @param name 字段的名称，类型为QString。
     * @return 返回字段在表格中的列索引，如果未找到则返回-1。
     */
    int getColByFieldName(const QString& name);

    /**
     * @brief 将对象转换为Json对象。
     * @return 返回一个空的Json对象。
     */
    virtual QJsonObject toJson() {return QJsonObject();}

    /**
     * @brief 从Json对象中加载数据，更新当前对象。
     * @param json 要加载的Json对象。
     */
    virtual void fromJson(const QJsonObject &json) {}

    /**
     * @brief 更新复制对象的名称。
     * @param startIndex 复制对象的起始索引，默认值为0。
     */
    virtual void updateCopyName(int startIndex = 0){}

    /**
     * @brief 创建一个空的模型对象。
     * @return 返回一个指向IModel接口的智能指针。
     * @note 这是一个纯虚函数，需要在派生类中实现。
     */
    virtual QSharedPointer<IModel> createEmpty() = 0;

    /**
     * @brief 同步后端数据，用于修改
     * @param 同步信号数据到服务器或者从服务器同步下来，由dir控制，默认是同步到服务器
     */
    virtual bool sync(bool dir = true) = 0;

    // variant转字符串
    QString variant2String(QVariant v);

    /**
     * @brief 获得字段的值描述映射
     * @param fieldName 字段名称
     * @return QMap<int,QString> 字段值和描述的映射
     */
    QMap<int,QString> getValueDesMap(const QString& fieldName);
    virtual QMap<int,QString> getValueDesMap(const QString& fieldName,bool bupdate);

    /**
     * @brief 添加子模型
     * @param id 子模型的唯一标识
     * @param child 子模型的智能指针
     */
    void appendChild(quint32 id, QSharedPointer<IModel> child){m_childMap[id] = child;}

    int childCount(){return m_childMap.size();}

    QMap<quint32, QSharedPointer<IModel> > childMap(){return m_childMap;}

    /**
     * 获取可编辑字段的映射信息。
     *
     * 该函数不接受任何参数。
     *
     * @return QMap<QString,bool> 类型的映射，其中键为字段名称，值为布尔值，
     *         表示该字段是否可编辑。如果字段可编辑，值为true；否则为false。
     */
    QMap<QString,bool> getEditableFieldMap();

    int fieldCount() const; // 获取字段计数
    void setFieldCount(int newFieldCount); // 设置字段计数

    QMap<quint32, QSharedPointer<IModel> > getChildMap() const; // 获取子模型映射

    bool isFieldEditable(const QString& field) const;    //字段是否可编辑

    QMap<QString, QMap<int, QString> > getFieldValueMap() const;

    bool fieldEnPluginEdit(const QString& field);
    QString fieldPluginName(const QString& field);

    bool fieldTextShow(const QString& field);

    bool fieldIsEnBg(const QString& field);
    QString fieldBg(const QString& field);


signals:
    void fieldCountChanged(); // 字段计数改变信号

protected:
    QMap<QString,QMap<int,QString>> m_fieldValueMap; // 字段的值和描述的映射
    QMap<QString,bool> m_fieldEditableMap;  //字段和是否允许编辑的映射

    QMap<QString,bool> m_enPluginEdit;  //字段是否启用插件编辑
    QMap<QString,QString> m_fieldPluginMap;  //插件名字

    QMap<QString,bool> m_showField;  //文本是否显示
    QMap<QString,QString> m_backgroundField;  //字段背景颜色

private:
    int m_fieldCount = 0; // 字段计数
    QMap<quint32,QSharedPointer<IModel>> m_childMap; // 子模型映射
    Q_PROPERTY(int fieldCount READ fieldCount WRITE setFieldCount NOTIFY fieldCountChanged)

public:
    quint32 id = 0;//ID信息
};
Q_DECLARE_METATYPE(IModel*)

#endif // CSTRUCT_H
